package com.abc.cloud.controller;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.ObjectUtil;
import com.abc.cloud.common.utils.JwtUtil;
import com.abc.cloud.common.utils.UserHolder;
import com.abc.cloud.dto.file.FileChunkDto;
import com.abc.cloud.entity.UserEntity;
import com.abc.cloud.vo.file.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.abc.cloud.entity.FileEntity;
import com.abc.cloud.service.FileService;
import com.abc.cloud.common.utils.PageUtil;
import com.abc.cloud.common.utils.Result;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 文件信息表
 *
 * @author LiJunXi
 * @email 2770063826@qq.com
 * @date 2023-10-27 13:09:54
 */
@Api(tags = "文件接口")
@RestController
@RequestMapping("/file")
public class FileController {
    @Autowired
    private FileService fileService;

    /**
     * 获取回收站文件列表
     */
    @ApiOperation(value = "获取回收站文件列表")
    @GetMapping("/getDeleteFile")
    public Result list(@RequestParam Map<String, Object> params){
        PageUtil page = fileService.queryPage(params);

        return Result.success(page, "page");
    }


    /**
     * 信息
     */
    @ApiOperation(value = "获取文件信息")
    @GetMapping("/info/{id}")
    public Result info(@PathVariable("id") Long id){
		FileEntity file = fileService.getById(id);

        return Result.success(file, "file");
    }

    /**
     * 保存文件夹或修改文件
     */
    @ApiOperation(value = "保存文件夹或修改文件")
    @PostMapping("/saveFolder")
    public Result saveFolder(@RequestBody FileSave fileSave){
		fileService.saveFolder(fileSave);

        return Result.success(null, "操作成功");
    }

    /**
     * 删除
     */
    @ApiOperation(value = "删除文件信息")
    @PutMapping("/delete")
    public Result delete(@RequestBody Long[] ids){
		fileService.removeByIds(Arrays.asList(ids));

        return Result.success(null, "");
    }


    /**
     * 检查分块
     * @param fileUploadCheck
     * @return
     */
    @ApiOperation(value = "检查分块")
    @PostMapping("/checkChunk")
    public Map<String, Object> checkChunk(@RequestBody FileUploadCheck fileUploadCheck){

        return fileService.checkChunk(fileUploadCheck);
    }


    /**
     * 上传分块文件
     */
    @ApiOperation(value = "上传分块文件")
    @PostMapping("/uploadChunk")
    public Result<FileChunkDto> uploadChunk(FileUpload fileUpload) throws Exception{
        Boolean flag = fileService.uploadChunk(fileUpload);
        if (flag) return Result.success(null, "文件分块上传成功");
        else return Result.fail(null, "文件分块上传出错");
    }


    /**
     * 合并文件
     * @param fileMerge
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "合并文件")
    @PostMapping("/mergeChunks")
    public Result mergeChunks(@RequestBody FileMerge fileMerge) {
        FileEntity fileEntity = new FileEntity();
        fileEntity.setFilename(fileMerge.getFilename());
        fileEntity.setFileMd5(fileMerge.getFileMd5());
        fileEntity.setPId(fileMerge.getFolderId());

        fileService.mergeChunks(fileMerge, fileEntity);

        return Result.success(null, "合并成功");
    }

    /**
     * 查找文件夹的内容
     * @param params
     * @return
     */
    @ApiOperation(value = "查找文件夹的内容")
    @GetMapping("/getFolderFile")
    public Result<PageUtil> getFolderFile(@RequestParam Map<String, Object> params){
        PageUtil page = fileService.getFolderFile(params);

        return Result.success(page, "获取文件夹数据成功");
    }

    /**
     * 只获取用户文件夹（不包含文件）
     * @param params
     * @return
     */
    @ApiOperation(value = "只获取用户文件夹（不包含文件）")
    @GetMapping("/getFolderList")
    public Result<List<FileEntity>> getFolderList(@RequestParam Map<String, Object> params){
        List<FileEntity> fileEntityList = fileService.getFolderList(params);

        return Result.success(fileEntityList, "获取文件夹成功");
    }

    /**
     * 获取文件流
     * @param response
     * @param fileId
     */
    @ApiOperation(value = "获取文件流")
    @GetMapping("/getFile/{fileId}")
    public void getFile(HttpServletResponse response,
                        HttpServletRequest request,
                        @PathVariable("fileId") Long fileId,
                        @CookieValue(name = "token", required = false) String tokenCookie,
                        @RequestParam(value = "token", required = false) String tokenParam){
        Long userId = null;
        if (tokenCookie != null) userId = JwtUtil.getUserId(tokenCookie);
        else if (tokenParam != null) userId = JwtUtil.getUserId(tokenParam);
        fileService.getFile(response, request, fileId, userId);
    }


    /**
     * 上传图片等小文件，返回链接
     * @param file
     * @return
     */
    @ApiOperation(value = "上传图片等小文件，返回链接")
    @PostMapping("/upload")
    public Result<String> upload(MultipartFile file){
        UserEntity userEntity = UserHolder.getUser();
        Long userId = userEntity.getId();
        String username = userEntity.getUsername();
        String str = fileService.upload(file, userId, username);

        return Result.success(str, "上传文件成功");
    }

    @ApiOperation("保存文件到我的云盘")
    @PostMapping("/saveFileToMe")
    public Result<String> saveFileToMe(@RequestBody FileSaveToMe fileSaveToMe){
        UserEntity user = UserHolder.getUser();
        Long fromUserId = fileSaveToMe.getUserId();
        Long fileId = fileSaveToMe.getFileId();
        String username = user.getUsername();
        Long userId = user.getId();
        LocalDateTime now = LocalDateTime.now();

        fileService.saveFileToMe(fileId, fileSaveToMe.getSaveFileId(), now, username, userId, fromUserId);

        return Result.success(null, "上传文件成功");
    }

    /**
     * 管理员获取文件列表
     * @param params
     * @return
     */
    @ApiOperation(value = "管理员获取文件列表")
    @GetMapping("/admin/getFileList")
    public Result<PageUtil> adminGetFileList(@RequestParam Map<String, Object> params){
        PageUtil pageUtil = fileService.adminGetFileList(params);

        return Result.success(pageUtil, "成功");
    }

    /**
     * 管理员更新文件信息
     * @param fileAdminUpdate
     * @return
     */
    @ApiOperation(value = "管理员更新文件信息")
    @PutMapping("/admin/updateFile")
    public Result adminUpdateFile(@RequestBody FileAdminUpdate fileAdminUpdate){
        fileService.adminUpdateFile(fileAdminUpdate);

        return Result.success(null, "操作成功");
    }

    /**
     * 管理员删除文件（更新文件状态）
     * @param fileIds
     * @return
     */
    @ApiOperation(value = "管理员删除文件（更新文件状态）")
    @PutMapping("/admin/updateStatus/{status}")
    public Result adminDeleteFile(@RequestBody List<Long> fileIds,
                                  @PathVariable("status") Integer status){
        fileService.adminDeleteFile(fileIds, status);

        return Result.success(null, "操作成功");
    }

    /**
     * 管理员更新用户文件（或某个文件）的评论状态
     * @param fileCommentAdminUpdate
     * @return
     */
    @ApiOperation(value = "管理员更新用户文件（或某个文件）的评论状态")
    @PutMapping("/admin/updateFileComment")
    public Result adminUpdateFileComment(@RequestBody FileCommentAdminUpdate fileCommentAdminUpdate){
        Long fileId = fileCommentAdminUpdate.getFileId();
        Long userId = fileCommentAdminUpdate.getUserId();
        Integer status = fileCommentAdminUpdate.getCommentType();
        if (fileId != null){
            fileService.adminUpdateFileComment(userId, fileId, status);
        }
        else{
            fileService.adminUpdateFileComment(userId, status);
        }

        return Result.success(null, "操作成功");
    }
}
